Модуль:Calendar
УСТАРЕВШАЯ ВЕРСИЯ МОДУЛЯ. НОВАЯ ВЕРСИЯ - Модуль:Calendar2 -- Модуль для работы календаря (Project:Календарь). Если собираетесь использовать его на других проектах — не забывайте указывать источник, откуда вы его взяли. local str = {} local result = '' function str.generate(frame) --Получение параметров local new_args = str._getParameters( frame.args, {'days', 'month', 'prevstart', 'prevfin', 'birthdays'} ); local days = tonumber( new_args'days' ) or 28; local month = new_args'month' or "Буп" local birthdays = tostring(new_args'birthdays') or "" local prevstart = new_args'prevstart' or 0 local prevfin = new_args'prevfin' or 0 --Генерация заголовка месяца local result = mw.html.create('div') :css({ "margin-top" = "20px", "margin-bottom" = "20px", "text-align" = "center", "font-family" = "Segoe UI Regular, Trebuchet MS, sans-serif", "font-size" = "40px", "color" = "white", "text-shadow" = "2px 2px 2px #000017" }) result = result:wikitext(month):tag( 'br' ):done() --Переменная для понимания наличия дней прошло месяца local prevdays = prevfin - prevstart local totaldays = days + prevdays + 1 -- Если месяц начинается с понедельника — присваиваем -1 как особый триггер if (prevstart prevfin and tonumber(prevstart) 0) then prevdays = prevdays - 1 end if prevdays -1 then totaldays = totaldays - 1 end -- Рассчёт кол-ва недель для отображения local cyclecount = math.ceil(totaldays / 7) -- Создание таблицы с информацией о событиях local btable = str.splitBD(birthdays) --Старт генерации календаря local calend = mw.html.create('div') -- Подписи дней calend:node(mw.html.create('span'):addClass("calend"):wikitext("Пн"):done()) calend:node(mw.html.create('span'):addClass("calend"):wikitext("Вт"):done()) calend:node(mw.html.create('span'):addClass("calend"):wikitext("Ср"):done()) calend:node(mw.html.create('span'):addClass("calend"):wikitext("Чт"):done()) calend:node(mw.html.create('span'):addClass("calend"):wikitext("Пт"):done()) calend:node(mw.html.create('span'):addClass("calend calweekend"):wikitext("Сб"):done()) calend:node(mw.html.create('span'):addClass("calend calweekend"):wikitext("Вс"):done()) calend:node(mw.html.create('br'):done()) -- Числовая часть for i=1,cyclecount do if (i 1 and prevdays > -1) then -- первая неделя + есть дни предыдущего месяца for j=1,7 do if j > 5 then -- j>5 - суббота и воскресенье if(j <= prevdays+1) then calend:node(mw.html.create('span'):addClass("calend calothermonthwe"):wikitext(prevstart-1+j):done()) -- если предыдущий месяц - не ищем событие, а просто записываем день else -- иначе ищем событие и добавляем его, если оно есть local ind = str.bdIndex(btable, j-prevdays-1) if ind ~= nil then local gen = str.generateWeekendTag(btableind, j-prevdays-1) calend:node(gen) else calend:node(mw.html.create('span'):addClass("calend calweekend"):wikitext(j-prevdays-1):done()) end end else -- аналогично, но для будней if(j <= prevdays+1) then calend:node(mw.html.create('span'):addClass("calend calothermonth"):wikitext(prevstart-1+j):done()) else local ind = str.bdIndex(btable, j-prevdays-1) if ind ~= nil then local gen = str.generateTag(btableind, j-prevdays-1) calend:node(gen) else calend:node(mw.html.create('span'):addClass("calend"):wikitext(j-prevdays-1):done()) end end end end calend:node(mw.html.create('br'):done()) else --цикл по остальным неделям for j=1,7 do local day = (7*(i-1))+j --подсчёт дней внутри цикла, чтобы не было 32 января if prevdays > -1 then day = day - 1 - prevdays end if j > 5 then if day > days then calend:node(mw.html.create('span'):addClass("calend calothermonthwe"):wikitext(day-days):done()) else local ind = str.bdIndex(btable, day) if ind ~= nil then local gen = str.generateWeekendTag(btableind, day) calend:node(gen) else calend:node(mw.html.create('span'):addClass("calend calweekend"):wikitext(day):done()) end end else if day > days then calend:node(mw.html.create('span'):addClass("calend calothermonth"):wikitext(day-days):done()) else local ind = str.bdIndex(btable, day) if ind ~= nil then local gen = str.generateTag(btableind, day) calend:node(gen) else calend:node(mw.html.create('span'):addClass("calend"):wikitext(day):done()) end end end end calend:node(mw.html.create('br'):done()) end end local fin = tostring(result) .. tostring(calend) return tostring(fin) end --Функция разбиения списка событий. Возвращает таблицу с записями. function str.splitBD(birthdays) local t = {} local ff = str.Split(birthdays, ";") for k,v in pairs(ff) do tk = v end return t end --Функция проверки наличия определённого дня среди записей событий function str.bdIndex(btable, number) for k,v in pairs(btable) do local strpart = string.sub(v, 1,3) strpart = string.gsub(strpart, "\-", "") strpart = string.gsub(strpart, "%a", "") if (tonumber(number) - tonumber(strpart) 0) then return k end end return nil end --Функция создания span'a определённого дня с определённым событием function str.generateTag(bdstr, day) local result = mw.html.create('span') local ff = str.Split(bdstr, "-") local caltype = ff2 if caltype "bd" then result = result:addClass("calend caltooltip cltporange"):wikitext(day):node(mw.html.create('span'):wikitext(ff3):done()):done() elseif caltype "event" then result = result:addClass("calend caltooltip cltpblue"):wikitext(day):node(mw.html.create('span'):wikitext(ff3):done()):done() else result = result:addClass("calend caltooltip cltpmixed"):wikitext(day):node(mw.html.create('span'):wikitext(ff3):done()):done() end return result end --Функция создания span'a определённого дня с определённым событием (в субботу или воскресенье) function str.generateWeekendTag(bdstr, day) local result = mw.html.create('span') local ff = str.Split(bdstr, "-") local caltype = ff2 if caltype "bd" then result = result:addClass("calend calweekend caltooltip cltporange"):wikitext(day):node(mw.html.create('span'):wikitext(ff3):done()):done() elseif caltype "event" then result = result:addClass("calend calweekend caltooltip cltpblue"):wikitext(day):node(mw.html.create('span'):wikitext(ff3):done()):done() else result = result:addClass("calend calweekend caltooltip cltpmixed"):wikitext(day):node(mw.html.create('span'):wikitext(ff3):done()):done() end return result end --Функция разбиения строки с использованием выбранного разделителя. Честно взято из документации по Lua. function str.Split(str, delim, maxNb) -- Eliminate bad cases... if string.find(str, delim) nil then return { str } end if maxNb nil or maxNb < 1 then maxNb = 0 -- No limit end local result = {} local pat = "(.-)" .. delim .. "()" local nb = 0 local lastPos for part, pos in string.gfind(str, pat) do nb = nb + 1 resultnb = part lastPos = pos if nb maxNb then break end end -- Handle the last field if nb ~= maxNb then result+ 1 = string.sub(str, lastPos) end return result end -- Получение параметров function str._getParameters( frame_args, arg_list ) local new_args = {}; local index = 1; local value; for i,arg in ipairs( arg_list ) do value = frame_argsarg if value nil then value = frame_argsindex; index = index + 1; end new_argsarg = value; end return new_args; end return str;